//
//  MolonRequestHelper.m
//
//  Created by Molon on 13-10-4.
//  Copyright (c) 2013年 Molon. All rights reserved.
//

#import "MolonRequestHelper.h"
#import "ModelArray.h"
#import "Model.h"
#import "MLClassPropManager.h"
#import "NSString+MLKit.h"
#import "MLDataHelper.h"
#import "NSDictionary+MLKit.h"
#import "MLKitDebug.h"
#import "NSObject+MLKitDAO.h"

@interface MolonRequestHelper()

@property (nonatomic, copy) NSString *methodName;

@end

@implementation MolonRequestHelper

- (id)init
{
    self = [super init];
    if (self) {
        self.methodName = [self configureMethodName];
        self.responseData = nil;
    }
    return self;
}

- (void)dealloc
{
    self.responseData = nil;
}

#pragma mark - helper
- (void)seObject:(id)object forKey:(NSString*)key toMutableDictionary:(NSMutableDictionary*)params{
    if (object&&![object isKindOfClass:[NSNull class]]) {
        NSAssert([object isKindOfClass:[NSString class]]||[object isKindOfClass:[NSNumber class]]||([object isKindOfClass:[NSURL class]]&&![object isFileURL]), @"参数必须为数字或者字符串类型或者非本地URL类型");
        
        if ([object isKindOfClass:[NSString class]]&&[NSString IsNilOrEmpty:object]) {
            return;
        }
        
        if ([object isKindOfClass:[NSURL class]]) {
            [params setObject:[object absoluteString] forKey:key];
        }else{
            [params setObject:object forKey:key];
        }
    }
}

-(id)valueForUndefinedKey:(NSString *)key {
    return nil;
}

#pragma mark - get params
- (NSMutableDictionary *)getRequestParams
{
    NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
    
    NSDictionary *propToTypes = [[MLClassPropManager manager]propToTypesOfClass:[self class] untilSuperClass:[MolonRequestHelper class] ignoreUntilClass:YES];
    for (NSString *key in [propToTypes allKeys]) {
        if (!key || ![key hasPrefix:@"p_"]){
            continue;
        }
        id object = [self valueForKey:key];
        [self seObject:object forKey:[key substringFromIndex:2] toMutableDictionary:params];
    }
    
    if (self.otherParamsBeforeRequestBlock) {
        NSDictionary *otherParams = self.otherParamsBeforeRequestBlock(self);
        for (id key in otherParams) {
            NSAssert([key isKindOfClass:[NSString class]], @"otherParams的key必须为字符串类型");
            
            id object = otherParams[key];
            [self seObject:object forKey:key toMutableDictionary:params];
        }
    }
    
    return params;
}

- (NSMutableDictionary *)getRequestFiles
{
    NSMutableDictionary *files = [NSMutableDictionary dictionary];
    
    //属性以f_为前缀的则为文件路径
    NSDictionary *propToTypes = [[MLClassPropManager manager]propToTypesOfClass:[self class] untilSuperClass:[MolonRequestHelper class] ignoreUntilClass:YES];
    for (NSString *key in [propToTypes allKeys]) {
        if (![key hasPrefix:@"f_"]){
            continue;
        }
        id object = [self valueForKey:key];
        if (object&&![object isKindOfClass:[NSNull class]]) {
            NSURL *filePath = nil;
            if ([object isKindOfClass:[NSString class]]) {
                filePath = [NSURL fileURLWithPath:object];
            }else if ([object isKindOfClass:[NSURL class]]) {
                filePath = object;
            }
            if (!filePath) {
                NSAssert(@"文件地址%@无效 --> %@", object,NSStringFromSelector(_cmd));
                continue;
            }
            [files setObject:filePath forKey:[key substringFromIndex:2]];
        }
    }
    
    return files;
}

- (void)handleResponseDataWithArray:(NSMutableArray *)responseInfo
{
    //检查是否有resultModelArray的key，没有就是有异常
    NSDictionary *propToTypes = [[MLClassPropManager manager]propToTypesOfClass:[self class] untilSuperClass:[MolonRequestHelper class] ignoreUntilClass:YES];
    
    static NSString *resultModelArrayKey = @"resultModelArray";
    NSAssert(propToTypes[resultModelArrayKey], @"请求%@必须存在resultModelArray属性才可",self);
    
    NSString *type = propToTypes[resultModelArrayKey];
    //T@"ModelArray" 截取出来类名部分
    type = [type substringWithRange:NSMakeRange(3, [type length]-4)];
    Class cls = NSClassFromString(type);
    
    NSAssert([cls isSubclassOfClass:[ModelArray class]], @"请求%@的resultModelArray属性必须是ModelArray的子类才可",self);
    
    [self setValue:[cls turnObject:(id)responseInfo] forKey:resultModelArrayKey];
}

- (void)handleResponseDataWithDictionary:(NSMutableDictionary *)responseInfo
{
    self.responseData = responseInfo;
    
    responseInfo = [responseInfo dictionaryWithLowercaseKeys];
    
    //自动把字典里的值赋给对应名称属性
    NSDictionary *propToTypes = [[MLClassPropManager manager]propToTypesOfClass:[self class] untilSuperClass:[MolonRequestHelper class] ignoreUntilClass:YES];
    
    static NSString *resultModelKey = @"resultModel";
    //如果有resultModel，则直接使用resultModel接收结果
    if (propToTypes[resultModelKey]) {
        NSString *type = propToTypes[resultModelKey];
        //T@"Model" 截取出来类名部分
        type = [type substringWithRange:NSMakeRange(3, [type length]-4)];
        Class cls = NSClassFromString(type);
        if ([cls isSubclassOfClass:[Model class]]&&[responseInfo isKindOfClass:[NSDictionary class]]) {
            //是model的子类
            [self setValue:[cls turnObject:(id)responseInfo] forKey:resultModelKey];
            return;
        }
    }
    
    for (NSString *key in [propToTypes allKeys]) {
        //没有r_标记说明其不需要处理
        if (![key hasPrefix:@"r_"]) continue;
        
        NSString *keyNonPrefix = [key substringFromIndex:2];
        id object = responseInfo[[keyNonPrefix lowercaseString]]; //info里的key全部为小写
        [self setValue:object forKey:key andKeyType:propToTypes[key]];
    }
    
}

#pragma mark - description and copy
- (NSString*)description
{
    NSMutableDictionary *parameters = [self getRequestParams];
    NSMutableDictionary *files = [self getRequestFiles];
    [parameters addEntriesFromDictionary:files];
    
    NSString *description = [NSString stringWithFormat:@"%@:\nMethodName:%@\nParams:\n%@\n",NSStringFromClass([self class]),self.methodName,parameters];
    
    return description;
}

- (id)copyWithZone:(NSZone *)zone {
    id helper = [[[self class] allocWithZone:zone] init];
    
    NSDictionary *propToTypes = [[MLClassPropManager manager]propToTypesOfClass:[self class] untilSuperClass:[MolonRequestHelper class] ignoreUntilClass:NO];
    
    for (NSString *key in [propToTypes allKeys]) {
        //默认是浅copy
        [helper setValue:[self valueForKey:key] forKey:key];
    }
    
    return helper;
}

#pragma mark - override
- (void)doSomethingBeforeSend
{
}

- (void)doSomethingAfterRequestSuccess
{
}

- (void)doSomethingAfterCachePreloaded
{
    [self doSomethingAfterRequestSuccess];
}

- (NSString*)configureMethodName
{
	[self doesNotRecognizeSelector:_cmd];
    
    return nil;
}

- (NSTimeInterval)customTimeoutInterval
{
    return -0.01f;
}

#pragma mark - setter
- (void)setState:(MolonRequestHelperState)state
{
    _state = state;
    
    if (self.stateChangedBlock) {
        self.stateChangedBlock(state,self);
    }
}

#pragma mark - getter
- (BOOL)isRequestCompleted
{
    return self.state == MolonRequestHelperStateRequestSuccess||self.state==MolonRequestHelperStateRequestFailed||self.state == MolonRequestHelperStateRequestError;
}


#pragma mark - cacahe 相关
- (NSTimeInterval)cacheValidTime
{
    return -1.0f;
}


@end